loadfile("lib/status.lua")()
loadfile("lib/state_machine.lua")()
loadfile("lib/turtle_utils.lua")()

function d()
	return statusGetProgData()
end

function atOddColumn()
	return (((d().x + 2) / 3) % 2) == 1
end

progStates = {
	init=function()
		forward(1)
		d().x = 1
		d().z = 1
		d().y = 1
		d().facing = 0
		statusSave()
		return 'lookLeft'
	end,
	forward=function()
		if not forward(1) then
			return 'end'
		end
		if atOddColumn() then
			d().z = d().z + 1
			if d().z > cfg.len then
				return 'turnStep1'
			end
		else
			d().z = d().z - 1
			if d().z < 1 then
				return 'turnStep1'
			end
		end
		
		return 'lookLeft'
	end,
	lookLeft=function()
		turtle.turnLeft()
		d().facing = 1
		return 'harvest'
	end,
	harvest=function()
		turtle.dig()
		turtle.select(2)
		turtle.place()
		if d().facing == 1 then
			return 'unLookLeft'
		else
			return 'unLookRight'
		end
	end,
	unLookLeft=function()
		turtle.turnRight()
		d().facing = 0
		return 'lookRight'
	end,
	lookRight=function()
		turtle.turnRight()
		d().facing = 2
		return 'harvest'
	end,
	unLookRight=function()
		turtle.turnLeft()
		d().facing = 0
		return 'forward'
	end,
	turnStep1=function()
		if d().x >= cfg.cols then
			return 'returnStep1'
		end
		if atOddColumn() then
			turtle.turnRight()
		else
			turtle.turnLeft()
		end
		return 'turnStep2'
	end,
	turnStep2=function()
		if not forward(1) then
			return 'end'
		end
		d().x = d().x + 1
		return 'turnStep3'
	end,
	turnStep3=function()
		if not forward(1) then
			return 'end'
		end
		d().x = d().x + 1
		return 'turnStep4'
	end,
	turnStep4=function()
		if not forward(1) then
			return 'end'
		end
		d().x = d().x + 1
		return 'turnStep5'
	end,
	turnStep5=function()
		if atOddColumn() then
			turtle.turnLeft()
		else
			turtle.turnRight()
		end
		return 'forward'
	end,
	returnStep1=function()
		turtle.turnRight()
		return 'returnStep2'
	end,
	returnStep2=function()
		if d().x <= 1 then
			return 'returnStep3'
		end
		if not forward(1) then
			return 'end'
		end
		d().x = d().x - 1
		return 'returnStep2'
	end,
	returnStep3=function()
		turtle.turnLeft()
		return 'returnStep4'
	end,
	returnStep4=function()
		for i=3, 16 do
			turtle.select(i)
			if not turtle.compareTo(2) then
				turtle.drop()
			else
				turtle.transferTo(2)
			end
		end
		return 'returnStep5'
	end,
	returnStep5=function()
		turtle.turnRight()
		return 'returnStep6'
	end,
	returnStep6=function()
		turtle.turnRight()
		return 'end'
	end,
}

arg = { ... }

configFileName = 'farm.cfg'

cfg = nil

if (arg[1] == nil) then
	if not statusLoad() then
		print("Usage: farm config LENGTH COLUMNS\n       farm run")
	else
		cfg = unserialize(configFileName)

		smStart(progStates)
	end
elseif (arg[1] ~= 'config' and arg[1] ~= 'run') then
	print("Usage: farm config LENGTH COLUMNS\n       farm run")
elseif arg[1] == 'config' and (arg[2] == nil or arg[3] == nil) then
	print("Usage: farm config LENGTH COLUMNS\n       farm run")
else
	action = arg[1]
	if action == 'config' then
		cfg = unserialize(configFileName) or {}
		cfg.len = tonumber(arg[2])
		cfg.cols = tonumber(arg[3]) * 6 - 2
		serialize(cfg, configFileName)
	else
		cfg = unserialize(configFileName)
		if cfg == nil then
			print("error: farm is not configured")
		else
			if not statusLoad() then
				statusInit('farm')
			end
			smStart(progStates)
		end
	end
end